/**
 * @author 0283000115
 * @date 2017年10月27日-下午4:35:46
 */
package com.zte.claa.inficombo.csa.app.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author 0283000115
 *
 */
public class ZipUtil {
	private static final Logger logger = LoggerFactory.getLogger(ZipUtil.class);
			
	/** 
     * 压缩文件-由于out要在递归调用外,所以封装一个方法用来 
     * @param zip -- 压缩目标zip文件的完整路径.
     * @param path -- 待压缩文件在zip中的目录，可填"";
     * @param srcFiles 
     * @throws IOException 
     * @author isea533 
     */  
    public static void ZipFiles(String zippath, String rootEntryPath, File... srcFiles) throws IOException{  
        ZipOutputStream out = null;
        try{
        	String zipDir = zippath.replaceAll("\\\\", "/");
        	int index = zipDir.lastIndexOf("/");
        	if(index >= 0){
        		zipDir = zipDir.substring(0, index);
        	} else {
        		zipDir = "";
        	}
        	File dir = new File(zipDir);
        	if(!dir.exists() && dir.isDirectory()){
        		dir.mkdirs();
        	}
        	out = new ZipOutputStream(new FileOutputStream(zippath));  
        	ZipFiles(out, rootEntryPath, srcFiles); 
        }finally{
        	if(out != null){
        		try{
        			out.close();
        			out = null;
        		}catch(Exception e){
        			logger.error("ZipFiles close failed: "+e.getMessage(), e);
        		}
        	}
        } 
    }  
    /** 
     * 压缩文件-File 
     * @param zipFile  zip文件 
     * @param srcFiles 被压缩源文件 
     * @author isea533 
     */  
    public static void ZipFiles(ZipOutputStream out, String rootEntryPath, File... srcFiles){  
    	rootEntryPath = rootEntryPath.replaceAll("\\\\", "/");  
        if(!rootEntryPath.equals("") && !rootEntryPath.endsWith("/")){  
        	rootEntryPath+="/";  
        }  
        byte[] buf = new byte[1024];  
        try {  
            for(int i=0;i<srcFiles.length;i++){  
                if(srcFiles[i].isDirectory()){  
                    File[] files = srcFiles[i].listFiles();  
                    String srcPath = srcFiles[i].getName();  
                    srcPath = srcPath.replaceAll("\\\\", "/");  
                    if(!srcPath.endsWith("/")){  
                        srcPath+="/";  
                    }  
                    out.putNextEntry(new ZipEntry(rootEntryPath+srcPath));  
                    ZipFiles(out,rootEntryPath+srcPath,files);  
                }  
                else{  
                    FileInputStream in = null;
					try {
						in = new FileInputStream(srcFiles[i]);
						System.out.println(rootEntryPath + srcFiles[i].getName());
						out.putNextEntry(new ZipEntry(rootEntryPath + srcFiles[i].getName()));
						int len;
						while ((len = in.read(buf)) > 0) {
							out.write(buf, 0, len);
						}
						out.closeEntry();
					}finally{
                    	in.close();  
                    }
                }  
            }  
        } catch (Exception e) {  
            logger.error("ZipFiles failed!", e);
        }  
    }
    
	/** 
     * 解压到指定目录 
     * @param zipPath 
     * @param descDir 
     */  
    public static void unZipFiles(String zipPath, String descDir)throws IOException{  
        unZipFiles(new File(zipPath), descDir);  
    }  
    
    /** 
     * 解压文件到指定目录 
     * @param zipFile 
     * @param descDir 
     * @author isea533 
     */  
    @SuppressWarnings("rawtypes")  
    public static void unZipFiles(File zipFile,String descDir)throws IOException{  
        File pathFile = new File(descDir);  
        if(!pathFile.exists()){  
            pathFile.mkdirs();  
        }  
        ZipFile zip = null;
        InputStream in = null;
        OutputStream out = null;
		try {
			zip = new ZipFile(zipFile);
			for (Enumeration entries = zip.entries(); entries.hasMoreElements();) {
				ZipEntry entry = (ZipEntry) entries.nextElement();
				String zipEntryName = entry.getName();
				try {
					in = zip.getInputStream(entry);
					String outPath = (descDir + "/" + zipEntryName).replaceAll("\\\\", "/");
					// 判断路径是否存在,不存在则创建文件路径
					File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
					if (!file.exists()) {
						file.mkdirs();
					}
					// 判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
					if (new File(outPath).isDirectory()) {
						continue;
					}
					// 输出文件路径信息
					logger.debug(outPath);
					out = new FileOutputStream(outPath);
					byte[] buf1 = new byte[1024];
					int len;
					while ((len = in.read(buf1)) > 0) {
						out.write(buf1, 0, len);
					}
				}finally{
					if(in != null){
						in.close();
						in = null;
					}
					if(out != null){
						out.close();
						out = null;
					}					
				}
			}
		}finally{
        	if(zip != null){
        		zip.close();
        		zip = null;
        	}
        }
    } 
      
    // test
    public static void main2(String[] args)   
    {  
        String zipFilePath = "D:\\zip\\claa_mote_20171103151121.zip";  
        String unzipFilePath = "D:\\zip000\\tmp123";  
        try   
        {  
        	File[] srcFiles = new File[]{new File("d:\\zip\\m3-20.data"), 
        			new File("d:\\zip\\m3-20.md5.txt"), new File("D:\\zip\\claa_mote_20171103151121")};
        	String zipFileDir = "d:\\zip000\\a.zip";
        	ZipFiles(zipFileDir, "", srcFiles);
        	System.out.println("zip ok");
        	unZipFiles(zipFileDir, "d:\\zip001");  
        	System.out.println("unzip OK!");
        }  
        catch (Exception e)  
        {  
            e.printStackTrace();  
        }  
    }  
    
}
